﻿using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Configuration;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using Hxsoft.AppV1.Module;

namespace Hxsoft.AppV1.WebUI
{
	/// <summary>
	/// 文章内容。
	/// </summary>
	public class ArticleContent : System.Web.UI.UserControl
	{

		private static string DisclaimerDataTemplate = StringExtensions.GetEffectiveValueOrDefault(ConfigurationManager.AppSettings["DisclaimerDataTemplate"], @"声明：上述内容仅供参考，并不构成投资与操作建议。据此入市，风险自担。");
		private static string DisclaimerMyTemplate = StringExtensions.GetEffectiveValueOrDefault(ConfigurationManager.AppSettings["DisclaimerMyTemplate"], @"声明：上述文章纯属作者个人观点，仅供参考，并不构成投资与操作建议。据此入市，风险自担。");
		private static string DisclaimerPermission = StringExtensions.GetEffectiveValueOrDefault(ConfigurationManager.AppSettings["DisclaimerPermission"], @"提示：您没有阅读本文的权限，显示内容为本文摘要。");

		protected virtual bool ShowDisclaimer
		{
			get
			{
				return true;
			}
		}
		
		private LoadedValue<int?> loadedArticleId;
		/// <summary>
		/// 查看文章内容的ID。
		/// </summary>
		public virtual int? ArticleId
		{
			get
			{
				if (loadedArticleId.Loader == null)
					loadedArticleId.Loader = () => IntExtensions.ParseOrNull(Request.QueryString[GenericUrlManager.Article_Query_InfoIdField]);
				return loadedArticleId.Value;
			}
		}

		private LoadedValue<int?> loadedCurrentPage;
		/// <summary>
		/// 查看文章内容的ID。
		/// </summary>
		public virtual int? CurrentPage
		{
			get
			{
				if (loadedCurrentPage.Loader == null)
					loadedCurrentPage.Loader = () => IntExtensions.ParseOrNull(Request.QueryString[GenericUrlManager.Article_Query_PageField]);
				return loadedCurrentPage.Value;
			}
		}

		private LoadedValue<string> loadedArticleCode;
		/// <summary>
		/// 查看文章内容的文章代码。
		/// </summary>
		public virtual string ArticleCode
		{
			get
			{
				if (loadedArticleCode.Loader == null)
					loadedArticleCode.Loader = () => Request.QueryString[GenericUrlManager.Article_Query_ArticleCodeField];
				return loadedArticleCode.Value;
			}
		}

		private LoadedValue<string> loadedModuleCode;
		/// <summary>
		/// 文章所属的栏目代码。
		/// </summary>
		public virtual string ModuleCode
		{
			get
			{
				if (loadedModuleCode.Loader == null)
					loadedModuleCode.Loader = () => Request.QueryString[GenericUrlManager.Article_Query_ModuleCodeField];
				return loadedModuleCode.Value;
			}
		}

		private LoadedValue<int?> loadedSiteId;
		/// <summary>
		/// 文章所属的站点。
		/// </summary>
		public virtual int? SiteId
		{
			get
			{
				if (loadedSiteId.Loader == null)
					loadedSiteId.Loader = () => Sites.CurrentSiteId;
				return loadedSiteId.Value;
			}
		}

		private LoadedValue<Module.Module> loadedModuleInfo;
		/// <summary>
		/// 文章所属的栏目ID。
		/// </summary>
		public virtual Module.Module ModuleInfo
		{
			get
			{
				if (loadedModuleInfo.Loader == null)
					loadedModuleInfo.Loader = () => SiteId.HasValue ? Modules.GetItem(SiteId.Value, ModuleCode) : null;
				return loadedModuleInfo.Value;
			}
		}

		private LoadedValue<int?> loadedModuleId;
		/// <summary>
		/// 文章所属的栏目ID。
		/// </summary>
		public virtual int? ModuleId
		{
			get
			{
				if (loadedModuleId.Loader == null)
					loadedModuleId.Loader = () => ModuleInfo == null ? new int?() : ModuleInfo.ModuleId;
				return loadedModuleId.Value;
			}
		}

		private LoadedValue<string> loadedModuleName;
		/// <summary>
		/// 文章所属的栏目名称。
		/// </summary>
		public virtual string ModuleName
		{
			get
			{
				if (loadedModuleName.Loader == null)
					loadedModuleName.Loader = () => ModuleInfo == null ? null : ModuleInfo.ModuleName;
				return loadedModuleName.Value;
			}
		}

		private LoadedValue<Article> loadedContent;
		/// <summary>
		/// 文章内容。
		/// </summary>
		public virtual Article Content
		{
			get
			{
				if (loadedContent.Loader == null)
					loadedContent.Loader = () =>
					{
						Article article = null;
                        if (!string.IsNullOrEmpty(ArticleCode))
                        {
                            article = Articles.Read(SiteId.Value, ArticleCode, IsAdd);
                            Response.Cookies["articleCodeCookie"].Value = ArticleCode;
                            Response.Cookies["readSiteCookie"].Value = SiteId.Value.ToString();
                        }
                        else if (ArticleId.HasValue)
                        {                            
                            article = Articles.Read(ArticleId.Value, IsAdd);
                            Response.Cookies["articleIdCookie"].Value=ArticleId.Value.ToString();
                        }
                        else
                        {                            
                            article = Articles.ReadModuleTopArticle(ModuleId.Value, IsAdd);
                            Response.Cookies["moduleIdCookie"].Value=ModuleId.Value.ToString();
                        }

						// 增加免责任声明
						if (!string.IsNullOrEmpty(ModuleName) && ModuleId.HasValue && ShowDisclaimer)
						{
							GenericModuleDataContext dc = new GenericModuleDataContext();
							Guid? resourceId = Resources.GetIdentifier(Modules.ArticleReleaseResourceCategoryId, SiteId, Modules.GetArticleReleaseResourceCode(ModuleId.Value));
							if (resourceId.HasValue)
							{
								bool b = dc.RolePermissions.GetRolesIsHasPermission(new string[] { Roles.EveryoneRoleName }, resourceId.Value, (int)Modules.ArticleReleasePermissionCode.Read);
								if (!b)
								{
									if (ModuleName.Contains("行情") || ModuleName.Contains("数据") || ModuleName.Contains("Market") || ModuleName.Contains("Data"))
										article.ArtContent += string.Format(@"<div class=""clean""></div><div class=""Disclaimer"">{0}</div>", DisclaimerDataTemplate);
									else
										article.ArtContent += string.Format(@"<div class=""clean""></div><div class=""Disclaimer"">{0}</div>", DisclaimerMyTemplate);
								}
							}
						}

                        foreach(KeywordForLinks.KeywordForLinkList kf in KeyWordForLinkList)
                        {
                            Regex regex = new Regex(kf.Keyword);
                            if (!string.IsNullOrEmpty(article.ArtContent))
                            {
                                article.ArtContent = regex.Replace(article.ArtContent, GetKeywordAndUrl(kf.Keyword, kf.LinkUrl), kf.Count);
                            }
                        }                       

						return article;
					};
				return loadedContent.Value;
			}
		}

        public string GetKeywordAndUrl(string keyword,string url)
        {
            return string.Format("<a class='KeywordLink' href='{0}'>{1}</a>", url, keyword);
        }

        private LoadedValue<List<KeywordForLinks.KeywordForLinkList>> loadedKeywordForLinkList;

        public List<KeywordForLinks.KeywordForLinkList> KeyWordForLinkList
        {
            get
            {
                if (loadedKeywordForLinkList.Loader == null)
                {
                    loadedKeywordForLinkList.Loader=()=>KeywordForLinks.GetList(SiteId);
                }
                return loadedKeywordForLinkList.Value;
            }
        }

        private bool IsAdd
        {
            get
            {
                HttpCookie articleCodeCookie = Request.Cookies["articleCodeCookie"];
                HttpCookie articleIdCookie = Request.Cookies["articleIdCookie"];
                HttpCookie moduleIdCookie = Request.Cookies["moduleIdCookie"];
                HttpCookie readSiteCookie = Request.Cookies["readSiteCookie"];
                if (articleCodeCookie == null && articleIdCookie == null && moduleIdCookie == null && readSiteCookie==null)
                    return true;
                
                if (ArticleId.HasValue && articleIdCookie != null && ArticleId.Value.ToString() == articleIdCookie.Value)
                    return false;

                if (!string.IsNullOrEmpty(ArticleCode) && articleCodeCookie != null && readSiteCookie!=null&& ArticleCode == articleCodeCookie.Value&&SiteId.Value.ToString()==readSiteCookie.Value)
                    return false;
                
                if (ModuleId.HasValue && moduleIdCookie != null && ModuleId.Value.ToString() == moduleIdCookie.Value)
                    return false;

                return true;

            }
        }

		private LoadedValue<bool> loadedShowEn;
		public bool ShowEn
		{
			get {
				if (loadedShowEn.Loader == null)
					loadedShowEn.Loader = () => (ViewState["ShowEn"] == null) ? false : (bool)ViewState["ShowEn"];
				return loadedShowEn.Value;
			}
			set {
				if (loadedShowEn.Setter == null)
					loadedShowEn.Setter = v => ViewState["ShowEn"] = v;
				loadedShowEn.Value = value;
			}
		}

		public virtual string ArticleSummary
		{
			get {
				string artContent = string.Empty;
				if (!String.IsNullOrEmpty(Content.Summary))
					artContent = Content.Summary.Trim();
				else
					artContent = StringExtensions.CutString(StringExtensions.HtmlDecode(StringExtensions.FilterHtmlTag(Content.ArtContent)), 200).Trim();

                foreach (KeywordForLinks.KeywordForLinkList kf in KeyWordForLinkList)
                {
                    Regex regex = new Regex(kf.Keyword);
                    if (!string.IsNullOrEmpty(artContent))
                    {
                        artContent = regex.Replace(artContent, GetKeywordAndUrl(kf.Keyword, kf.LinkUrl), kf.Count);
                    }
                }  

				string backUrl = string.IsNullOrEmpty(ArticleCode) ? GenericUrlManager.BuildArticleDetailUrl(ModuleCode, Content.ArticleId) : GenericUrlManager.BuildArticleDetailUrl(ModuleCode, ArticleCode);

				string loginUrl = null;
				
				if (Users.CurrentUserId == null)
					loginUrl = GenericUrlManager.BuildLoginUrl(backUrl, LoginWarningType.NotLogin);
				else
					loginUrl = GenericUrlManager.BuildLoginUrl(backUrl, LoginWarningType.NotRight);

				if (ShowEn)
					return string.Format(@"<p style=""text-indent:2em;"">{0}  <span class='Disclaimer'>[<a href=""{1}"" title=""Read more""> Read more </a>]</span></p>{2}", artContent, loginUrl, string.Format(@"<div class='Disclaimer'>{1} Read the full text, please<a href=""{0}"" title=""Click to Sign In"">  Sign In</a>.</div>", loginUrl, DisclaimerPermission));

				return string.Format(@"<p style=""text-indent:2em;"">{0}  <span class='Disclaimer'>[<a href=""{1}"" title=""阅读全文""> 阅读全文 </a>]</span></p>{2}", artContent, loginUrl, string.Format(@"<div class='Disclaimer'>{1}阅读全文，请<a href=""{0}"" title=""点击去登陆"">  登录</a> 。</div>", loginUrl, DisclaimerPermission));
			}
		}

		private LoadedValue<string> loadedRelatedLinks;
		/// <summary>
		/// 相关链接。
		/// </summary>
		public virtual string RelatedLinks
		{
			get
			{
				if (loadedRelatedLinks.Loader == null)
					loadedRelatedLinks.Loader = () =>
						{
							string link = Content.Link;
							if (!string.IsNullOrEmpty(link)) return link;

							var list = Articles.GetBaseList(SiteId, new Nullable<int>(), Content.Keywords, 20);
							if (list != null && list.Count > 0)
							{
								link = "<ul>";
								int? preId = null;
								for (int i = 0; i < list.Count && i < 6; i++)
								{
									var item = list[i];

									// 消除重复行
									if (preId.HasValue && preId.Value == item.ArticleId) continue;

									preId = item.ArticleId;
									link += @"<li><a href=""" + GenericUrlManager.BuildArticleDetailUrl(item.ModuleId, item.ArticleId) + @""" target=""_blank"">" + item.Title + "</a></li>";
								}
								link += "</ul>";
							}

							link = Articles.UpdateLink(Content.ArticleId, link);
							return link;
						};
				return loadedRelatedLinks.Value;
			}
		}

		public virtual string TitleImageUrl
		{
			get
			{
				return GenericUrlManager.GetInfoResourceThumbnailGeneratorUrl(Content.ImageType, null);
			}
		}

		private LoadedValue<List<string>> loadedPageContents;
		/// <summary>
		/// 当前页的内容。
		/// </summary>
		public virtual List<string> PageContents
		{
			get
			{
				if (loadedPageContents.Loader == null)
					loadedPageContents.Loader = () => Content.SplitContent();
				return loadedPageContents.Value;
			}
		}

		/// <summary>
		/// 当前页的内容。
		/// </summary>
		public string CurrentPageContent
		{
			get
			{
				if(PageContents == null || PageContents.Count <= 0) return "";
				int page = CurrentPage.GetValueOrDefault(1);
				if (page < 1) page = 1;
				if (page > PageContents.Count) page = PageContents.Count;
				return PageContents[page - 1];
			}
		}

		/// <summary>
		/// 页导航的Html。
		/// </summary>
		public virtual string PageNavHtml
		{
			get
			{
				if (PageContents == null || PageContents.Count <= 1) return "";
				string html = "";

				int page = CurrentPage.GetValueOrDefault(1);
				for (int i = 1; i <= PageContents.Count; i++)
				{
					if (i == page)
						html += @" <span class=""pagesCur"">" + i + @"</span> ";
					else
					{
						int? p = i;
						if (p == 1) p = null;
						string url = "";
						if (!string.IsNullOrEmpty(ArticleCode))
							url = GenericUrlManager.BuildArticleDetailUrl(ModuleId.Value, ArticleCode, p);
						else
							url = GenericUrlManager.BuildArticleDetailUrl(ModuleId.Value, ArticleId.Value, p);
						html += @" <a href=""" + url + @""">" + i + "</a> ";
					}
				}

				if (page > 1)
				{
					int? p = page - 1;
					if (p == 1) p = null;
					string url = "";
					if (!string.IsNullOrEmpty(ArticleCode))
						url = GenericUrlManager.BuildArticleDetailUrl(ModuleId.Value, ArticleCode, p);
					else
						url = GenericUrlManager.BuildArticleDetailUrl(ModuleId.Value, ArticleId.Value, p);

					html = @"<a href=""" + url + @""">上一页</a>" + html;
				}

				if (page < PageContents.Count)
				{
					string url = "";
					if (!string.IsNullOrEmpty(ArticleCode))
						url = GenericUrlManager.BuildArticleDetailUrl(ModuleId.Value, ArticleCode, page + 1);
					else
						url = GenericUrlManager.BuildArticleDetailUrl(ModuleId.Value, ArticleId.Value, page + 1);

					html += @"<a href=""" + url + @""">下一页</a>";
				}

				html = @"<div class=""pagination"">" + html + @"</div>";

				return html;
			}
		}





		/// <summary>
		/// 当页面加载时执行的操作。
		/// </summary>
		/// <param name="sender">发送事件的对象。</param>
		/// <param name="e">事件参数。</param>
		/// <remarks>进行了权限的检测。</remarks>
		public virtual void Page_Load(object sender, EventArgs e)
		{
			CheckRightAndDo();
		}

		public virtual void CheckRightAndDo()
		{
			GenericHelper.CheckLogin(string.IsNullOrEmpty(ArticleCode) ? GenericUrlManager.BuildArticleDetailUrl(ModuleCode, Content.ArticleId) : GenericUrlManager.BuildArticleDetailUrl(ModuleCode, ArticleCode), CheckRight);		
		}

		protected virtual void RewriteMeta()
		{
			this.Page.Title = Content.Title + Hxsoft.AppV1.Page.TitleSuffix;	// 更新页面标题

			Hxsoft.AppV1.Page page = this.Page as Hxsoft.AppV1.Page;
			if (page != null)		// 更新页面Meta
			{
				page.MetaKeywords = Content.Title + (Content.Keywords == null ? "" : "," + Content.Keywords);
				page.MetaDescription = Content.Summary;
			}
		}

		protected override void OnPreRender(EventArgs e)
		{
			RewriteMeta();

			base.OnPreRender(e);
		}

		/// <summary>
		/// 检测当前用户是否拥有查阅文章内容的权限。
		/// </summary>
		/// <returns>布尔值表示当前用户是否拥有查阅文章内容的权限。</returns>
		protected virtual bool CheckRight()
		{			
			return ModuleArticles.GetReadRight(ModuleArticles.GetItem(ModuleId.Value, Content.ArticleId));
		}



		private LoadedValue<Article> loadedNextArticle;
		/// <summary>
		/// 下一篇。
		/// </summary>
		public virtual Article NextArticle
		{
			get
			{
				if (loadedNextArticle.Loader == null)
					loadedNextArticle.Loader = () => Articles.GetNextArticle(ModuleId.Value, Content.ReleaseDate);
				return loadedNextArticle.Value;
			}
		}

		private LoadedValue<Article> loadedPrevArticle;
		/// <summary>
		/// 上一篇。
		/// </summary>
		public virtual Article PrevArticle
		{
			get
			{
				if (loadedPrevArticle.Loader == null)
					loadedPrevArticle.Loader = () => Articles.GetPrevArticle(ModuleId.Value, Content.ReleaseDate);
				return loadedPrevArticle.Value;
			}
		}
	}
}